Box ve DeReferansing
Pointlerlar içerisinde bir verinin adresini tutan veri yapısıdır. Bu adres bir veriyi işaret etmektedir. Aslında daha öncesinde çokça Rust içerisinde pointer
yapılarını kullandık. En yaygın kullanılan pointer ise Referans (&)
olmaktadır. Bu pointer yapılarının ekstra özellikleri bulunmamaktadır.
Bizlere normal referanslara göre ekstra özellik veren pointer
'lar akıllı pointerlar (smart pointers
) olmaktadır.
Smart Pointer
yapıları C++ ile geliştirilmiştir ve Rust'a özgü bir konsept değildir.
Rust üzerinde popüler olan akıllı pointerlara bakılacak olunursa bunlardan ilki olan box
heap
üzerinde tutulmaktadır. Bir diğeri de RC
olarak kısaltabileceğimiz Referance Count
olmaktadır. Bu yapı birden fazla sahibe izin vermektedir.
Box Smart Pointer
İlk olarak Box Smart Pointer
yapılarına bakacağız. Bu yapılar Rust'ın sunabileceği en düzgün Smart Pointer
yapıları olmaktadır. Bu yapılar sayesinde Stack
yerine Heap
üzerinde veri kaydedebiliriz. Ancak bu veriyi heap
üzerinde kaydetsek de pointer'ın kendisi Stack
üzerinde kaydedilecektir.
Hadi bir tupple oluşturarak başlayalım! Bir box yapısı oluştururken box
anahtar kelimesini kullanmaktayız. Sonrasında oluşturduğumuz bu box pointer
değerini yazdırabiliriz.
fn main() {
let t = {12, "eggs"};
let b = box::new(t);
println!("{:?}", b)
}
Kodumuzu çalıştırdığımızda aslında beklendiği üzere tuple içerisindeki değerlerin yazdırıldığını görüntüleyebildik. Ancak burada dikkat edilmesi gereken neyin kaydedildiği değil nereye kaydedildiğidir. Aslında tupple'lar stack üzerinde tutulmaktadır. Ancak biz bu tupple değerini box
methodu içerisine yerleştirdiğimizde tupple'ımız artık heap
içerisinde varlığını göstermeye başlamıştır. Tupple'ımız konumunu heap içerisine alsa da b
adı ile oluşturduğumuz ve bu tupple'ı işaret eden pointer
stack içerisinde tutulmaya devam etmiştir.
### DeReferance
Pointerlar aynı zamanda içerilerinde dereferance
yani referans kaldırıcı methodlar ile de gelmektedir. Bu durumu direkt olrak kod yapısında görüntüleyebiliriz.
let x = 5;
let y = &x;
Bir x değeri ve bu x değerinin referansına sahip bir y değeri oluşturduk
assert_eq!(5, x); // True
assert_eq!(5, y); // Error
Sonrasında bu değerleri kontrol etmek istediğimizde her ne kadar 5'in x'e eşit olduğunu görsek de y 5 değerinine değil de referansına sahip olduğu için Compiler bu kısımda karşılaştıramam hatası verdi. Bu durumu çözmek için referansı direkt veriye çeviren *
yapısını kullanabiliriz.
assert_eq!(5, x); // True
assert_eq!(5, *y); // True
Artık y de 5 değerine sahip oldu ve kodumuz sıkıntısız çalıştı.
Bu işlemleri yukarıda ifade edildiği üzere normal referans ile yapmış olsak da bu işlemleri box
referans ile de yapabiliriz.
let x = 5;
let y = Box::new(x);
assert_eq!(5, x); // True
assert_eq!(5, *y); // True